<?php

namespace backend\models;

use Yii;
use yii\behaviors\TimestampBehavior;
use yii\behaviors\BlameableBehavior;
use yii\db\Expression;
use yii\helpers\ArrayHelper;


/**
 * This is the model class for table "menu".
 *
 * @property integer $id
 * @property string $menu_name
 * @property integer $level
 * @property integer $parent_id
 * @property string $route
 * @property string $menu_icon
 * @property integer $display
 * @property integer $module_id
 * @property integer $created_at
 * @property integer $updated_at
 */
class Menu extends \yii\db\ActiveRecord
{


    /**
     * @inheritdoc
     */
    public static function tableName()
    {
        return 'menu';
    }

    /**
     * create_time, update_time to now()
     * crate_user_id, update_user_id to current login user id
     */
    public function behaviors()
    {
        return [
            TimestampBehavior::className(),
            // BlameableBehavior::className(),
        ];
    }

    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
			['menu_name', 'required'],
			['route', 'unique'],
            [['level', 'parent_id', 'sort','display', 'created_at', 'updated_at','module_id'], 'integer'],
            [['menu_name', 'menu_icon'], 'string', 'max' => 30],
            [['route'], 'string', 'max' => 50]
        ];
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels()
    {
        return [
            'id' => Yii::t('app', 'ID'),
            'menu_name' => Yii::t('app', 'Menu'),
            'level' => Yii::t('app', 'Level'),
            'parent_id' => Yii::t('app', 'Parent Id'),
            'route' => Yii::t('app', 'Route'),
            'menu_icon' => Yii::t('app','Menu Icon'),
            'display' => Yii::t('app','Display'),
            'sort' => Yii::t('app','Sort'),
            'module_id' => Yii::t('app','Module'),
            'created_at' => Yii::t('app','Created At'),
            'updated_at' => Yii::t('app','Updated At'),
        ];
    }

    public function afterSave($insert, $changedAttributes)
    {
        parent::afterSave($insert, $changedAttributes);
        $auth = Yii::$app->authManager;
        if($insert)
        {
            $permission = $auth->createPermission($this->route);
            $permission->description = $this->menu_name;
            $auth->add($permission);
			$admin = $auth->getRole('admin');
			$auth->addChild($admin, $permission);
        }else
        {
            //echo $this->route;exit;
            $route = ArrayHelper::getValue($changedAttributes,'route',$this->route);
            $permission = $auth->getPermission($route);
            //$permission = new stdClass();
            $permission->name = $this->route;
            $permission->description = $this->menu_name;
            $auth->update($route,$permission);
        }
    }
    public function afterDelete()
    {
        parent::afterDelete();
        //删除所有权限
        $auth = Yii::$app->authManager;
        if($p = $auth->getPermission($this->route))
            $auth->remove($p);
    }
    /**
     * 获取子菜单
     * @return static
     */
    public function getSon()
    {
        return $this->hasMany(Menu::className(),['parent_id'=>'id'])->orderBy('sort asc');
    }
    /**
     * 获取父菜单
     */
    public function getFather()
    {
        return $this->hasOne(Menu::className(),['id'=>'parent_id']);
    }
    /**
     * 生成菜单
     * @return string
     */
    public static function generateMenuByUser()
    {
        $list = TMenu::find()->where('level=1')->all();
        $menu = Yii::$app->controller->renderPartial('@backend/views/home/_menu',[
            'list'=>$list,
            'admin'=>(Yii::$app->user->id==1)?true:false
        ]);
        return $menu;
    }

    /**
     * 检查菜单是否有子菜单
     * @return static
     */
    public static function hasChild($id)
    {
        $child_count =  Menu::find()->where(['parent_id'=>$id,'display'=>1])->count();
        return $child_count>0 ? true : false ;
    }

	public static function getMenu($menu_id){
		$menu = Menu::find()->select(['id','parent_id','menu_name','level','route'])->where(['id'=>$menu_id])->one();
		return $menu;
	}
	
	
	public static function getAllMenus(){
		$menu_array = Menu::find()->select(['id','parent_id','menu_name','level'])->asArray()->all();

		//$menu_list = Menu::getTree(0, $menu_array);
		//return $menu_list;
		$menu_list=array();
		if($menu_array){
			foreach($menu_array as $item){
				$menu_list[$item['id']] = $item['menu_name'];	
			}
		}
		return $menu_list;
		
	}

    public static function getNameByRoute($route){
        $menu = Menu::find()->select(['menu_name'])->where(['route'=>$route])->one();
        if($menu){
            return $menu->menu_name;
        }
    }



    /**
     * Get all catalog order by parent/child with the space before child label
     * Usage: ArrayHelper::map(Catalog::get(0, Catalog::find()->asArray()->all()), 'id', 'label')
     * @param int $parentId  parent catalog id
     * @param array $array  catalog array list
     * @param int $level  catalog level, will affect $repeat
     * @param int $add  times of $repeat
     * @param string $repeat  symbols or spaces to be added for sub catalog
     * @return array  catalog collections
     */
    static public function getTree($parentId = 0, $array = [], $level = 1, $add = 2, $repeat = '　')
    {
        $strRepeat = '';
        // add some spaces or symbols for non top level categories
        if ($level >= 1) {
            for ($j = 0; $j < $level; $j++) {
                $strRepeat .= $repeat;
            }
        }

        $newArray = array ();
        //performance is not very good here
        foreach ((array)$array as $v) {
            if ($v['parent_id'] == $parentId) {
                $item = (array)$v;
                $item['name'] = $strRepeat . (isset($v['menu_name']) ? $v['menu_name'] : $v['name']);
                $newArray[] = $item;

                $tempArray = self::getTree($v['id'], $array, ($level + $add), $add, $repeat);
                if ($tempArray) {
                    $newArray = array_merge($newArray, $tempArray);
                }
            }
        }
        return $newArray;
    }

    static public function getMenuItems($parentId = 0, $array = [])
    {

        $newArray = array ();
        //performance is not very good here
        foreach ((array)$array as $k=>$v) {
            if ($v['parent_id'] == $parentId) {
                $item = (array)$v;
                $newArray[$k]['label'] = $item['menu_name'];
                $newArray[$k]['icon'] = !empty($item['menu_icon']) ? "fa fa-".$item['menu_icon'] : "fa fa-list-ul";
                $newArray[$k]['url'][] = $item['route'];
                if(!\Yii::$app->user->can($item['route'])){
                    $newArray[$k]['visible'] = false;
                }
                if(self::hasChild($v['id'])){
                    $newArray[$k]['options']['class'] = 'treeview';
                    $newArray[$k]['items'] = self::getMenuItems($v['id'], $array);
                }


            }
        }
        return $newArray;
    }



    static public function getTopMenuList(){

        $module_ids_array=Module::getAvailModule();
        $menus = Menu::find()->where(['level'=>'1','parent_id'=>0,'display'=>1,'module_id'=>$module_ids_array ])->orderBy('sort ASC')->asArray()->all();
        $menuLists = array();
        if($menus){
            foreach((array)$menus as $k=>$v){
                $menuLists[$k]['label'] = $v['menu_name'];
                $menuLists[$k]['url'] = $v['route'];
                $arrayRoute = explode('/', ltrim($v['route'], '/'));
                $module = Yii::$app->controller->module->getUniqueId();
                if($module==$arrayRoute[0]){
                    $menuLists[$k]['active'] = true;
                }
                if(!\Yii::$app->user->can($v['route'])){
                    $menuLists[$k]['visible'] = false;
                }

            }
        }

        return $menuLists;
    }

    static public function getTopMenusPermissions(){
        $module_ids_array=Module::getAvailModule();
        return Menu::find()->where(['level' => 1,'parent_id'=>0,'display'=>1,'module_id'=>$module_ids_array ])->orderBy('sort','ASC')->all();
    }




}
